home *** CD-ROM | disk | FTP | other *** search
/ 3D Games - Real-time Rend…ng & Software Technology / 3D Games - Real-time Rendering & Software Technology.iso / flysdk / plugin / car / car.cpp next >
Encoding:
C/C++ Source or Header  |  2000-11-21  |  16.1 KB  |  798 lines

  1. #include "..\..\lib\Fly3D.h"
  2. #include "..\gamelib\gamelib.h"
  3. #include "car.h"
  4.  
  5. void mp_message(int from,mp_msg *msg);
  6.  
  7. camera_desc cd_camera;
  8. car_desc cd_car;
  9. sun_desc cd_sun;
  10.  
  11. BOOL APIENTRY DllMain(HINSTANCE hModule, 
  12.                       DWORD  ul_reason_for_call, 
  13.                       LPVOID lpReserved)
  14. {    
  15.     switch( ul_reason_for_call ) 
  16.     {
  17.     case DLL_PROCESS_ATTACH:
  18.     case DLL_THREAD_ATTACH:
  19.     case DLL_THREAD_DETACH:
  20.     case DLL_PROCESS_DETACH:
  21.         break;
  22.     }
  23.     return TRUE;
  24. }
  25.  
  26. __declspec( dllexport )
  27. int num_classes()
  28. {
  29.     return 3;
  30. }
  31.  
  32. __declspec( dllexport )
  33. class_desc *get_class_desc(int i)
  34. {
  35.     switch(i)
  36.     {
  37.     case 0:
  38.         return &cd_camera;
  39.     case 1:
  40.         return &cd_car;
  41.     case 2:
  42.         return &cd_sun;
  43.     default: 
  44.         return 0;
  45.     }
  46. }
  47.  
  48. __declspec( dllexport )
  49. int fly_message(int msg,int param,void *data)
  50. {
  51.     switch(msg)
  52.     {
  53.     case FLYM_DRAWSCENE:
  54.         if (directx->mpmode!=FLYMP_SERVER)
  55.         {
  56.         // sets view
  57.         flyengine->set_camera(flyengine->cam);
  58.         
  59.         // draws the sun 
  60.         if (flyengine->cam->type==TYPE_CAMERA)
  61.             if (((camera *)flyengine->cam)->s) 
  62.                 ((camera *)flyengine->cam)->s->draw();
  63.  
  64.         // draws the scene
  65.         flyengine->draw_bsp(1);
  66.  
  67.         // draw stencil shadow filter polygon
  68.         if (flyengine->stencil)
  69.             {
  70.             flyengine->start_text_mode();
  71.             glEnable(GL_STENCIL_TEST);
  72.             glStencilFunc(GL_NOTEQUAL,0,~0);
  73.             glColor3fv(&flyengine->shadowcolor.x);
  74.             glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
  75.             glBlendFunc(GL_ZERO, GL_SRC_COLOR);
  76.             glRecti(0, 0, screen_sx, screen_sy);
  77.             glDisable(GL_STENCIL_TEST);
  78.             }
  79.         }
  80.         break;
  81.     case FLYM_DRAWTEXT:
  82.         if (directx->mpmode!=FLYMP_SERVER)
  83.         {
  84.         static DWORD t=timeGetTime();
  85.         static int frame_rate=0,frame_count=0;
  86.         static char str[256];
  87.         frame_count++;
  88.         if (flyengine->cur_time-t>1000)
  89.             {
  90.             frame_rate=frame_count*1000/(flyengine->cur_time-t);
  91.             t=flyengine->cur_time;
  92.             frame_count=0;
  93.             }
  94.         if (flyengine->cur_time - flyengine->status_msg_time > 2000)
  95.             {
  96.             sprintf(str,"FPS:%i N:%i",frame_rate,flyengine->nodedrawcount);
  97.             flyengine->draw_text( screen_sx-96, 0, str );
  98.             }
  99.         }
  100.         break;
  101.     case FLYM_UPDATESCENE:
  102.         {
  103.         bsp_object *obj=0;
  104.         while(obj=flyengine->get_next_active_object(obj,TYPE_CAR))
  105.             if (obj==flyengine->player)
  106.                 ((car *)obj)->check_keys(param);
  107.             else if (((car *)obj)->player==0)
  108.                     ((car *)obj)->check_robot_keys(param);
  109.         }
  110.         break;
  111.     case FLYM_MPUPDATE:
  112.         ((car *)flyengine->player)->mp_send_pos(FLYMP_MSG_POS,0);
  113.         return 0;
  114.     case FLYM_MPMESSAGE:
  115.         mp_message(param,(mp_msg *)data);
  116.         return 0;
  117.     }
  118.     return 1;
  119. }
  120.  
  121. bsp_object *car::clone()
  122. {
  123.     car *tmp=new car;
  124.     *tmp=*this;
  125.     tmp->source=this;
  126.     return tmp;
  127. }
  128.  
  129. int car::get_custom_param_desc(int i,param_desc *pd)
  130. {
  131.     if (pd!=0)
  132.     switch(i)
  133.     {
  134.     case 0:
  135.         pd->type='f';
  136.         pd->data=&maxvel;
  137.         strcpy(pd->name,"maxvel");
  138.         break;
  139.     case 1:
  140.         pd->type='f';
  141.         pd->data=&accel;
  142.         strcpy(pd->name,"accel");
  143.         break;
  144.     case 2:
  145.         pd->type='v';
  146.         pd->data=&veldamp;
  147.         strcpy(pd->name,"veldamp");
  148.         break;
  149.     case 3:
  150.         pd->type='f';
  151.         pd->data=&carwheelrot;
  152.         strcpy(pd->name,"carwheelrot");
  153.         break;
  154.     case 4:
  155.         pd->type='f';
  156.         pd->data=&carheight;
  157.         strcpy(pd->name,"carheight");
  158.         break;
  159.     case 5:
  160.         pd->type='f';
  161.         pd->data=&wheelmaxrot;
  162.         strcpy(pd->name,"wheelmaxrot");
  163.         break;
  164.     case 6:
  165.         pd->type='f';
  166.         pd->data=&wheelrotvel;
  167.         strcpy(pd->name,"wheelrotvel");
  168.         break;
  169.     case 7:
  170.         pd->type='f';
  171.         pd->data=&wheelrotdamp;
  172.         strcpy(pd->name,"wheelrotdamp");
  173.         break;
  174.     case 8:
  175.         pd->type='f';
  176.         pd->data=&wheelradius;
  177.         strcpy(pd->name,"wheelradius");
  178.         break;
  179.     case 9:
  180.         pd->type='f';
  181.         pd->data=&gravity;
  182.         strcpy(pd->name,"gravity");
  183.         break;
  184.     case 10:
  185.         pd->type='3';
  186.         pd->data=&carmesh;
  187.         strcpy(pd->name,"carmesh");
  188.         break;
  189.     case 11:
  190.         pd->type='3';
  191.         pd->data=&wheelmesh;
  192.         strcpy(pd->name,"wheelmesh");
  193.         break;
  194.     case 12:
  195.         pd->type='v';
  196.         pd->data=&wheelposft;
  197.         strcpy(pd->name,"wheelposft");
  198.         break;
  199.     case 13:
  200.         pd->type='v';
  201.         pd->data=&wheelposbk;
  202.         strcpy(pd->name,"wheelposbk");
  203.         break;
  204.     case 14:
  205.         pd->type='z';
  206.         pd->data=&track;
  207.         strcpy(pd->name,"track");
  208.         break;
  209.     case 15:
  210.         pd->type=TYPE_SHADOW;
  211.         pd->data=&carshadow;
  212.         strcpy(pd->name,"carshadow");
  213.         break;
  214.     }
  215.     return 16;
  216. }
  217.  
  218. void car::init()
  219. {
  220.     static vector delta(0,0,0);
  221.     if (source)
  222.         {
  223.         pos=source->pos+delta;
  224.         delta.z+=1000;
  225.         }
  226.     align_z(vector(0,0,1));
  227.     rotate(rot);
  228.  
  229.     if (track)
  230.         totaltracktime=(int)(track->length()/maxvel);
  231.  
  232.     if (wheelmesh && wheelmesh->edges==0)
  233.         wheelmesh->compute_normals(MESH_EDGES);
  234.     if (carmesh && carmesh->edges==0)
  235.         carmesh->compute_normals(MESH_EDGES);
  236. }
  237.  
  238. void car::draw()
  239. {
  240.     static light_vertex lights;
  241.     static vector viewpos,color,lightpos,v;
  242.  
  243.     sun *s=0;
  244.     if (flyengine->cam->type==TYPE_CAMERA)
  245.         s=((camera *)flyengine->cam)->s;
  246.  
  247.     if(carshadow && flyengine->stencil==0)
  248.         {
  249.         carshadow->reposition(this);
  250.         carshadow->draw();
  251.         }
  252.  
  253.     if (carmesh && wheelmesh)
  254.     {
  255.         lights.nlights=0;
  256.         if (s)
  257.             {
  258.             lightpos=(s->pos-pos)*mat_t;
  259.             color=s->color;
  260.             lights.add_light(lightpos,color,0);
  261.             }
  262.         else 
  263.             {
  264.             lightpos.null();
  265.             color.vec(1,1,1);
  266.             }
  267.  
  268.         static mat4x4 m1,m2;
  269.         m1.set_rotation(-wheelroll,vector(1,0,0));
  270.         m2.set_rotation(-wheelrot,vector(0,1,0));
  271.         m2=m2*m1;
  272.  
  273.         viewpos=(flyengine->cam->pos-pos)*mat_t;
  274.         float f=viewpos.length()/flyengine->viewmaxdist;
  275.         if (f<1.0f)
  276.             f=(1.0f-f)*flyengine->cartoonwidth;
  277.         else f=0.0f;
  278.  
  279.         glPushMatrix();
  280.         glTranslatef(pos.x,pos.y,pos.z);
  281.         glMultMatrixf((float *)&mat);
  282.         carmesh->draw_cartoon(viewpos,color,lights,f);
  283.  
  284.         v=viewpos*m1;
  285.         lights.pos[0]=lightpos*m1;
  286.         
  287.         glPushMatrix();
  288.         glTranslatef(wheelposbk.x,wheelposbk.y,wheelposbk.z);
  289.         glRotatef(wheelroll,1,0,0);
  290.         wheelmesh->draw_cartoon(v,color,lights,f);
  291.         glPopMatrix();
  292.  
  293.         glPushMatrix();
  294.         glTranslatef(-wheelposbk.x,wheelposbk.y,wheelposbk.z);
  295.         glRotatef(wheelroll,1,0,0);
  296.         wheelmesh->draw_cartoon(v,color,lights,f);
  297.         glPopMatrix();
  298.  
  299.         v=viewpos*m2;
  300.         lights.pos[0]=lightpos*m2;
  301.  
  302.         glPushMatrix();
  303.         glTranslatef(wheelposft.x,wheelposft.y,wheelposft.z);
  304.         glRotatef(wheelrot,0,1,0);
  305.         glRotatef(wheelroll,1,0,0);
  306.         wheelmesh->draw_cartoon(v,color,lights,f);
  307.         glPopMatrix();
  308.  
  309.         glPushMatrix();
  310.         glTranslatef(-wheelposft.x,wheelposft.y,wheelposft.z);
  311.         glRotatef(wheelrot,0,1,0);
  312.         glRotatef(wheelroll,1,0,0);
  313.         wheelmesh->draw_cartoon(v,color,lights,f);
  314.         glPopMatrix();
  315.  
  316.         glPopMatrix();
  317.     }
  318.     if (flyengine->stencil && s)
  319.         draw_stencil_shadow(lightpos);
  320. }
  321.  
  322. void car::draw_stencil_shadow(vector& lightpos)
  323. {
  324.     // compute light direction
  325.     vector lightdir=lightpos-pos;
  326.     lightdir.normalize();
  327.     lightdir*=flyengine->shadowdepth;
  328.  
  329.     // set current car pos and rotation
  330.     glPushMatrix();
  331.     glTranslatef(pos.x,pos.y,pos.z);
  332.     glMultMatrixf((float *)&mat);
  333.  
  334.     // draw body shadow
  335.     carmesh->draw_shadow_volume(lightdir);
  336.  
  337.     // draw back right wheel shadow
  338.     glPushMatrix();
  339.     glTranslatef(wheelposbk.x,wheelposbk.y,wheelposbk.z);
  340.     wheelmesh->draw_shadow_volume(lightdir);
  341.     glPopMatrix();
  342.  
  343.     // draw back left wheel shadow
  344.     glPushMatrix();
  345.     glTranslatef(-wheelposbk.x,wheelposbk.y,wheelposbk.z);
  346.     wheelmesh->draw_shadow_volume(lightdir);
  347.     glPopMatrix();
  348.  
  349.     // compute front wheel rotation 
  350.     static mat4x4 m;
  351.     m.set_rotation(-wheelrot,vector(0,1,0));
  352.     lightdir=lightdir*m;
  353.  
  354.     // draw front right wheel shadow
  355.     glPushMatrix();
  356.     glTranslatef(wheelposft.x,wheelposft.y,wheelposft.z);
  357.     glRotatef(wheelrot,0,1,0);
  358.     wheelmesh->draw_shadow_volume(lightdir);
  359.     glPopMatrix();
  360.  
  361.     // draw front left wheel shadow
  362.     glPushMatrix();
  363.     glTranslatef(-wheelposft.x,wheelposft.y,wheelposft.z);
  364.     glRotatef(wheelrot,0,1,0);
  365.     wheelmesh->draw_shadow_volume(lightdir);
  366.     glPopMatrix();
  367.  
  368.     glPopMatrix();
  369. }
  370.  
  371. int car::step(int dt)
  372. {
  373.     static vector p,v;
  374.  
  375.     // if no contact, apply gravity
  376.     if (!contactobj)
  377.         vel.z-=gravity*dt;
  378.  
  379.     // apply damping to the steering
  380.     if (wheelrot>=0.0f)
  381.         {
  382.         wheelrot-=wheelrotdamp*dt;
  383.         if (wheelrot<0.0f)
  384.             wheelrot=0.0f;
  385.         if (wheelrot>wheelmaxrot)
  386.             wheelrot=wheelmaxrot;
  387.         }
  388.     else
  389.         {
  390.         wheelrot+=wheelrotdamp*dt;
  391.         if (wheelrot>0.0f)
  392.             wheelrot=0.0f;
  393.         if (wheelrot<-wheelmaxrot)
  394.             wheelrot=-wheelmaxrot;
  395.         }
  396.  
  397.     float len=vel.length();
  398.     // if moving
  399.     if (len>0.01f)
  400.     {
  401.         // normalize velocity
  402.         vel/=len;
  403.         if (len>maxvel)
  404.             len=maxvel;
  405.         
  406.         // project velocity in car local axes
  407.         v.x=vec_dot(vel,X)*len;
  408.         v.y=vec_dot(vel,Y)*len;
  409.         v.z=vec_dot(vel,Z)*len;
  410.  
  411.         // apply damping to individual axes
  412.         // X for sliding and Z for breaking
  413.         for( int i=0;i<3;i++ )
  414.             if (v[i]>=0.0f)
  415.                 {
  416.                 v[i]-=veldamp[i]*dt;
  417.                 if (v[i]<0.0) v[i]=0.0f;
  418.                 }
  419.             else
  420.                 {
  421.                 v[i]+=veldamp[i]*dt;
  422.                 if (v[i]>0.0) v[i]=0.0f;
  423.                 }
  424.         
  425.         // restore velocity vector from axes components
  426.         vel=X*v.x + Y*v.y + Z*v.z;
  427.  
  428.         // compute wheel roll based on forward motion and wheel radius
  429.         wheelroll+=v.z*dt/(M_2Pi*wheelradius)*360.0f;
  430.         wheelroll=(float)fmod(wheelroll,360);
  431.         
  432.         // move by applying the car velocity
  433.         p=pos+vel*(float)dt;
  434.         flyengine->excludecollision=this;
  435.         if (flyengine->collision_bsp(flyengine->bsp,pos,p))
  436.         {
  437.             contactobj=flyengine->hitmesh;
  438.             contactfacenum=flyengine->hitface;
  439.         }
  440.         else contactobj=0;
  441.         flyengine->excludecollision=0;
  442.         if (contactobj)
  443.             pos=flyengine->hitip+contactobj->faces[contactfacenum]->normal*carheight;
  444.         else pos=p;
  445.     } 
  446.     else v.null();
  447.  
  448.     if (contactobj==0)
  449.     {
  450.         // ray intesect collision detection to check for ground contact
  451.         p=pos-Y*carheight;
  452.         flyengine->excludecollision=this;
  453.         if (flyengine->collision_bsp(flyengine->bsp,pos,p))
  454.         {
  455.             contactobj=flyengine->hitmesh;
  456.             contactfacenum=flyengine->hitface;
  457.         } 
  458.         else contactobj=0;
  459.         flyengine->excludecollision=0;
  460.     }
  461.     
  462.     // if in contact
  463.     if (contactobj)
  464.     {
  465.         // position the car at a fixed distance from the ground
  466.         pos=flyengine->hitip+Y*(carheight-0.1f);
  467.         // align car with ground if no collision with wall
  468.          if (contactobj->localfaces==0 && contactobj->faces[contactfacenum]->normal.z<0.5f)
  469.         {
  470.             rotate(Y,vector(0,0,1));
  471.             v.z=-v.z;
  472.             v.x=-v.x;
  473.         }
  474.         else rotate(Y,contactobj->faces[contactfacenum]->normal,0.1f*dt);
  475.         // recompute velocity
  476.         vel=X*v.x + Y*v.y + Z*v.z;
  477.         // rotate car body based on forward motion and steering angle if in contact
  478.         rotate(-wheelrot*v.z*dt/carwheelrot,Y);
  479.     }
  480.  
  481.     return 1;
  482. }
  483.  
  484. void car::check_keys(int dt)
  485. {
  486.     unsigned char *diks=directx->diks;
  487.     
  488.     if (diks[0xcb])    // left arrow
  489.         wheelrot+=wheelrotvel*dt;
  490.  
  491.     if (diks[0xcd])    // right arrow
  492.         wheelrot-=wheelrotvel*dt;
  493.  
  494.     if (contactobj)
  495.     {
  496.     if (diks[0xc8])    // up arrow
  497.         vel-=Z*(accel*dt);
  498.  
  499.     if (diks[0xd0])    // down arrow
  500.         vel+=Z*(accel*dt);
  501.     }
  502. }
  503.  
  504. void car::check_robot_keys(int dt)
  505. {
  506.     if (track==0)
  507.         return;
  508.  
  509.     vector P,T,V;
  510.     float len,dot;
  511.  
  512.     // get position of rabbit
  513.     curtracktime=(curtracktime+dt)%totaltracktime;
  514.     track->evaluate((float)curtracktime/totaltracktime,&P.x);
  515.     P.z+=track->pivot.z-50;
  516.     T=P-pos;
  517.     len=T.length();
  518.     T/=len;
  519.     dot=vec_dot(T,Z);
  520.     if (dot<0.996)   // 0.996=cosd(8)
  521.         {
  522.         V.cross(T,Z);
  523.         if (vec_dot(V,Y)>0)
  524.             wheelrot+=wheelrotvel*dt; // rotate right
  525.         else
  526.             wheelrot-=wheelrotvel*dt; // rotate left
  527.         }
  528.  
  529.     if (contactobj)
  530.     if (len>500)
  531.         vel-=Z*(accel*dt); // move forward
  532. }
  533.  
  534. void car::mp_send_pos(int msgtype,int msgflag)
  535. {
  536.     static struct mp_data data;
  537.     
  538.     data.type=msgtype;
  539.     data.dpid=directx->players[player].dpid;
  540.     data.flag=msgflag;
  541.     data.pos=pos;
  542.     data.vel=vel;
  543.     data.Y=Y;
  544.     data.Z=Z;
  545.     data.wheelrot=wheelrot;
  546.  
  547.     directx->send_message((mp_msg *)&data,sizeof(struct mp_data));
  548. }
  549.  
  550. void mp_message(int from,mp_msg *msg)
  551. {    
  552.     switch( msg->type )
  553.         {
  554.         case FLYMP_MSG_POS:
  555.             {
  556.                 mp_data *data=(mp_data *)&msg->type;
  557.                 car *c=(car *)directx->players[from].data;
  558.                 if (from>0)
  559.                     {
  560.                     c->remove_from_bsp();
  561.                     c->pos=data->pos;
  562.                     c->vel=data->vel;
  563.                     c->Y=data->Y;
  564.                     c->Z=data->Z;
  565.                     c->X.cross(c->Y,c->Z);
  566.                     c->wheelrot=data->wheelrot;
  567.                     c->update_mat();
  568.                     c->add_to_bsp();
  569.                     }
  570.             }
  571.             break;
  572.         case FLYMP_MSG_JOIN:
  573.             {
  574.                 player_data *data=(player_data *)&msg->type;
  575.                 car *c=(car *)flyengine->player->clone();
  576.                 c->player=directx->add_player(data->name,data->dpid,c);
  577.                 flyengine->set_status_msg("%s HAS JOINED THE GAME",data->name);
  578.                 flyengine->activate(c,(directx->mpmode==FLYMP_SERVER));
  579.             }
  580.             break;
  581.         case FLYMP_MSG_QUIT:
  582.             {
  583.                 player_data *data=(player_data *)&msg->type;
  584.                 if (from<directx->nplayers)
  585.                     {
  586.                     flyengine->set_status_msg("%s HAS LEFT THE GAME",directx->players[from].name);
  587.                     bsp_object *obj=(bsp_object *)directx->remove_player(from);
  588.                     for( int i=from;i<directx->nplayers;i++ )
  589.                         ((car *)directx->players[i].data)->player=i;
  590.                     if (obj) obj->life=-1;
  591.                     }
  592.             }
  593.             break;
  594.         }
  595. }
  596.  
  597. bsp_object *camera::clone()
  598. {
  599.     camera *tmp=new camera;
  600.     *tmp=*this;
  601.     tmp->source=this;
  602.     return tmp;
  603. }
  604.  
  605. int camera::get_custom_param_desc(int i,param_desc *pd)
  606. {
  607.     if (pd!=0)
  608.     switch(i)
  609.     {
  610.     case 0:
  611.         pd->type='f';
  612.         pd->data=&height;
  613.         strcpy(pd->name,"height");
  614.         break;
  615.     case 1:
  616.         pd->type='f';
  617.         pd->data=&dist;
  618.         strcpy(pd->name,"dist");
  619.         break;
  620.     case 2:
  621.         pd->type='d';
  622.         pd->data=⌖
  623.         strcpy(pd->name,"target");
  624.         break;
  625.     case 3:
  626.         pd->type='f';
  627.         pd->data=&maxvel;
  628.         strcpy(pd->name,"maxvel");
  629.         break;
  630.     case 4:
  631.         pd->type=TYPE_SUN;
  632.         pd->data=&s;
  633.         strcpy(pd->name,"sun");
  634.         break;
  635.     }
  636.     return 5;
  637. }
  638.  
  639. void camera::init()
  640. {
  641.     if (target)
  642.     {
  643.     lp=target->pos;
  644.     pos=target->source->pos;
  645.     }
  646. }
  647.  
  648. int camera::step(int dt)
  649. {
  650.     vector dir,p;
  651.  
  652.     if (target)
  653.         {
  654.         dir.x=target->pos.x-pos.x;
  655.         dir.y=target->pos.y-pos.y;
  656.         dir.z=0;
  657.         dir.normalize();
  658.  
  659.         p.x=target->pos.x-dir.x*dist;
  660.         p.y=target->pos.y-dir.y*dist;
  661.         p.z=target->pos.z+height;
  662.  
  663.         float dist;
  664.         dir=p-pos;
  665.         dist=dir.length();
  666.         if (dist>0.01f)
  667.             {
  668.             dir/=dist;
  669.             if (dist>maxvel*dt)
  670.                 dist=maxvel*dt;
  671.             pos+=dir*dist;        
  672.             }
  673.         
  674.         if (flyengine->collision_bsp(flyengine->bsp,pos,vector(pos.x,pos.y,pos.z-flyengine->viewmindist*2)))
  675.             pos.vec(flyengine->hitip.x,flyengine->hitip.y,flyengine->hitip.z+flyengine->viewmindist*2);
  676.  
  677.         dir=target->pos-lp;
  678.         dist=dir.length();
  679.         if (dist>0.01f)
  680.             {
  681.             dir/=dist;
  682.             if (dist>maxvel*dt)
  683.                 dist=maxvel*dt;
  684.             lp+=dir*dist;        
  685.             }
  686.  
  687.         dir=pos-lp;
  688.         dir.normalize();
  689.         align_z(dir);
  690.         }
  691.  
  692.     return 1;
  693. }
  694.  
  695. bsp_object *sun::clone()
  696. {
  697.     sun *tmp=new sun;
  698.     *tmp=*this;
  699.     tmp->source=this;
  700.     return tmp;
  701. }
  702.  
  703. int sun::get_custom_param_desc(int i,param_desc *pd)
  704. {
  705.     if (pd!=0)
  706.     switch(i)
  707.     {
  708.     case 0:
  709.         pd->type='3';
  710.         pd->data=&objmesh;
  711.         strcpy(pd->name,"objmesh");
  712.         break;
  713.     case 1:
  714.         pd->type='c';
  715.         pd->data=&color;
  716.         strcpy(pd->name,"color");
  717.         break;
  718.     case 2:
  719.         pd->type='f';
  720.         pd->data=&color.w;
  721.         strcpy(pd->name,"transp");
  722.         break;
  723.     case 3:
  724.         pd->type='p';
  725.         pd->data=&halopic;
  726.         strcpy(pd->name,"halopic");
  727.         break;
  728.     case 4:
  729.         pd->type='f';
  730.         pd->data=&halosize;
  731.         strcpy(pd->name,"halosize");
  732.         break;
  733.     }
  734.     return 5;
  735. }
  736.  
  737. void sun::init()
  738. {
  739.     if (objmesh)
  740.         pos=objmesh->pivotpos;
  741. }
  742.  
  743. void sun::draw()
  744. {
  745.     static vector x,y;
  746.  
  747.     int d=(int)(pos-flyengine->cam->pos).length()/10*10;
  748.     glMatrixMode( GL_PROJECTION );
  749.     glPushMatrix();
  750.     glLoadIdentity();
  751.     gluPerspective( flyengine->camangle, flyengine->aspect, d/2,2*d);
  752.     glMatrixMode( GL_MODELVIEW );
  753.  
  754.     glDisable(GL_FOG);
  755.     glDisable(GL_DEPTH_TEST);
  756.  
  757.     glPushMatrix();
  758.     glTranslatef(pos.x,pos.y,pos.z);
  759.     if (objmesh)
  760.         objmesh->draw();
  761.  
  762.     x=flyengine->cam->X*halosize;
  763.     y=flyengine->cam->Y*halosize;
  764.  
  765.     glBlendFunc(GL_ONE,GL_ONE);
  766.     glDepthMask(GL_FALSE);
  767.     
  768.     glColor3f(color.x*color.w,color.y*color.w,color.z*color.w);
  769.  
  770.     tc->use(halopic);
  771.  
  772.     glBegin(GL_QUADS);
  773.  
  774.     glTexCoord2f(1,0);
  775.     glVertex3f(x.x-y.x, x.y-y.y, x.z-y.z);
  776.  
  777.     glTexCoord2f(1,1);
  778.     glVertex3f(x.x+y.x, x.y+y.y, x.z+y.z);
  779.  
  780.     glTexCoord2f(0,1);
  781.     glVertex3f(y.x-x.x, y.y-x.y, y.z-x.z);
  782.  
  783.     glTexCoord2f(0,0);
  784.     glVertex3f(-x.x-y.x, -x.y-y.y, -x.z-y.z);
  785.  
  786.     glEnd();
  787.     glPopMatrix();
  788.  
  789.     glDepthMask(GL_TRUE);
  790.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  791.     glEnable(GL_DEPTH_TEST);
  792.     if (flyengine->fog) glEnable(GL_FOG);
  793.  
  794.     glMatrixMode( GL_PROJECTION );
  795.     glPopMatrix();
  796.     glMatrixMode( GL_MODELVIEW );
  797. }
  798.